using Auth.Api;
using Auth.Application;
using Auth.Application.Services;
using Auth.Domain.Entities;
using Auth.Infrastructure.Repositories;
using Consul;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using SqlSugar;
using System.Reflection;
using System.Text;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllers();
builder.Services.AddAutoMapper(typeof(Auth.Application.AutoMapping));
// 添加Swagger服务
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new OpenApiInfo { Title = "Auth API", Version = "v1" });

    // 为Swagger添加XML注释
    var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
    var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
    c.IncludeXmlComments(xmlPath);

    // 添加JWT认证支持
    c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
    {
        Description = "JWT Authorization header using the Bearer scheme.",
        Name = "Authorization",
        In = ParameterLocation.Header,
        Type = SecuritySchemeType.ApiKey,
        Scheme = "Bearer"
    });

    c.AddSecurityRequirement(new OpenApiSecurityRequirement
    {
        {
            new OpenApiSecurityScheme
            {
                Reference = new OpenApiReference
                {
                    Type = ReferenceType.SecurityScheme,
                    Id = "Bearer"
                }
            },
            new string[] { }
        }
    });
});

//添加JWT认证
builder.Services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
    options.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuer = true,
        ValidateAudience = true,
        ValidateLifetime = true,
        ValidateIssuerSigningKey = true,
        ValidIssuer = builder.Configuration["Jwt:Issuer"],
        ValidAudience = builder.Configuration["Jwt:Audience"],
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:SecretKey"]))
    };
});

// 添加SqlSugar
builder.Services.AddSingleton<ISqlSugarClient>(db =>
{
    var sqlSugar = new SqlSugarClient(new ConnectionConfig
    {
        ConnectionString = builder.Configuration.GetConnectionString("conn"),
        DbType = DbType.MySql,
        IsAutoCloseConnection = true
    });

    return sqlSugar;
});



// 添加Consul客户端
builder.Services.AddSingleton<IConsulClient, ConsulClient>(p => new ConsulClient(cfg =>
{
    cfg.Address = new Uri("http://120.26.197.100:8500");
}));

// 添加服务
builder.Services.AddScoped(typeof(IAuthRepository<>), typeof(AuthRepository<>));
builder.Services.AddScoped<IAuthService, AuthService>();

// 添加CORS
builder.Services.AddCors(options =>
{
    options.AddDefaultPolicy(policy =>
    {
        policy.AllowAnyOrigin()
              .AllowAnyHeader()
              .AllowAnyMethod();
    });
});

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

// 添加CORS中间件
app.UseCors();

// 添加认证和授权中间件
app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();

using (var scope = app.Services.CreateScope())
{
    // 初始化数据库表
    var db = app.Services.GetRequiredService<ISqlSugarClient>();
    db.CodeFirst.InitTables(typeof(UserModel), typeof(RoleModel));
}

// 健康检查端点
app.MapGet("/health", () => Results.Ok("Ok"));

// 注册到Consul
var consulClient = app.Services.GetRequiredService<IConsulClient>();
var registration = new AgentServiceRegistration
{
    ID = $"Auth-{Guid.NewGuid()}",
    Name = "Auth",
    //Address = "localhost",
    //Port = 7225, // 请根据实际端口调整
    Address = "120.26.197.100",
    Port = 8080, // 请根据实际端口调整
    Check = new AgentServiceCheck
    {
        HTTP = $"http://120.26.197.100:8080/health",
        Interval = TimeSpan.FromSeconds(10),
        Timeout = TimeSpan.FromSeconds(5),
        DeregisterCriticalServiceAfter = TimeSpan.FromMinutes(1)
    }
};
consulClient.Agent.ServiceRegister(registration).Wait();

app.Run(); 